package com.ruoyi.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.project.domain.entity.*;
import com.ruoyi.project.domain.query.ProjectFeeQuery;
import com.ruoyi.project.domain.query.ProjectPayQuery;
import com.ruoyi.project.domain.query.ProjectPhaseQuery;
import com.ruoyi.project.mapper.ProjectPayMapper;
import com.ruoyi.project.mapper.ProjectPhaseMapper;
import com.ruoyi.project.service.*;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class ProjectPhaseServiceImpl extends ServiceImpl<ProjectPhaseMapper, ProjectPhase> implements IProjectPhaseService {

    @Resource
    private ProjectPhaseMapper projectPhaseMapper;

    @Resource
    private IProjectService projectService;

    @Resource
    private ISysDictTypeService dictTypeService;

    @Resource
    private IPhaseDictionaryService dictionaryService;

    @Resource
    private IProjectParticipanService joinPersonService;

    @Resource
    private IProjectFeeService feeService;

    @Resource
    private  IProjectAccountingService accountingService;

    @Resource
    private  IProjectWarrantyService warrantyService;


    @Resource
    private IProjectAllocationDetailService detailService;



    //分页
    @Override
    public TableDataInfo getPage(ProjectPhaseQuery query) {
        Page<Object> page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ProjectPhase> list = projectPhaseMapper.getList(query);
        return new TableDataInfo(list, page.getTotal());
    }

    //新增
    @Override
    public Boolean addInfo(ProjectPhase project) {
        //先查询该项目插入的阶段有没有 有先删除 之和有可能会有回退环节功能 导致多次插入
        LambdaQueryWrapper<ProjectPhase> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ProjectPhase::getProjectNo, project.getProjectNo())
                .eq(ProjectPhase::getPhaseId, project.getPhaseId());
        this.remove(queryWrapper);
        project.setOperator(SecurityUtils.getLoginUser().getUser().getNickName());

        PhaseDictionary byId = dictionaryService.getById(project.getPhaseId());
        project.setStatus("1");
        project.setPhaseName(byId.getPhaseName());
        project.setAudit(new ArrayList<>());

        //判断是不是插入归档环节信息 如果是 查询结算金额和所有收款总和是否相等 是则直接设置状态为已归档
        if ("7".equals(project.getPhaseId())) {
            boolean isCompelete = projectCompelete(project);
            if (isCompelete) {
                project.setStatus("2");
            }
        }

        //判断是不是插入质保环节 如果是  查询核算信息 如果核算信息填的质保金是0 自动生成一条质保信息 需要先查询有无质保信息 可能是回退的  确保只能插入一条
        //改动 不管是否有质保金 都生成一条信息
        if ("6".equals(project.getPhaseId())) {
            LambdaQueryWrapper<ProjectAccounting> accountingWrapper = new QueryWrapper<ProjectAccounting>().lambda()
                    .eq(ProjectAccounting::getProjectNo, project.getProjectNo())
                    .eq(ProjectAccounting::getAudit,"4");//审核通过的

            List<ProjectAccounting> accountingList = accountingService.list(accountingWrapper);
            BigDecimal warranty = BigDecimal.ZERO;
            for (ProjectAccounting projectAccounting : accountingList) {
                warranty = warranty.add(projectAccounting.getRetentionMoney()!=null?projectAccounting.getRetentionMoney():BigDecimal.ZERO);
            }

            //查询是否已有质保信息 有则不插入  改为更新一下质保金 其余原有的信息保留
            LambdaQueryWrapper<ProjectWarranty> warrantyWrapper = new QueryWrapper<ProjectWarranty>().lambda();
            warrantyWrapper.eq(ProjectWarranty::getProjectNo, project.getProjectNo());
            List<ProjectWarranty> warrantyList = warrantyService.list(warrantyWrapper);
            if (CollectionUtils.isNotEmpty(warrantyList)) {
            Project projectInfo = projectService.getById(project.getProjectNo());
                //如果质保金是0  自动生成一条质保信息信息
                ProjectWarranty warrantyEntity = warrantyList.get(0);
                warrantyEntity.setSettlementAmount(projectInfo.getSettlementAmount());
//                warrantyEntity.setReceivedAmount(BigDecimal.ZERO);
                warrantyEntity.setCompany(projectInfo.getCustomerName());
                warrantyEntity.setWarranty(warranty);
                warrantyService.updateById(warrantyEntity);
            }
            //可能提成有变化 重新设置一下确认分配
            checkConfirm(project.getProjectNo());
        }

        //判断是否是插入归档环节 是则更新一下质保信息的status为2 已完成 回退质保环节的时候需要更新状态？
        if ("7".equals(project.getPhaseId())) {
            try {
                LambdaQueryWrapper<ProjectWarranty> warrantyWrapper = new QueryWrapper<ProjectWarranty>().lambda();
                warrantyWrapper.eq(ProjectWarranty::getProjectNo, project.getProjectNo());
                ProjectWarranty warranty = warrantyService.getOne(warrantyWrapper);
                warranty.setStatus("2");
                warrantyService.updateById(warranty);
            } catch (Exception e) {
                throw new RuntimeException("后端接口出错,请联系管理员,错误码next");
            }
            //可能提成有变化 重新设置一下确认分配
            checkConfirm(project.getProjectNo());
        }

        boolean save = this.save(project);
        //创建支付信息
        if (save){
            projectService.createPay(project.getProjectNo());
        }
        return save;
    }

    @Override
    public Boolean addSaleInfo(ProjectPhase project) {
        //先查询该项目插入的阶段有没有 有先删除 之和有可能会有回退环节功能 导致多次插入
        LambdaQueryWrapper<ProjectPhase> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ProjectPhase::getProjectNo, project.getProjectNo())
                .eq(ProjectPhase::getPhaseId, project.getPhaseId());
        this.remove(queryWrapper);
        project.setOperator(SecurityUtils.getLoginUser().getUser().getNickName());

        PhaseDictionary byId = dictionaryService.getById(project.getPhaseId());
        project.setPhaseName(byId.getPhaseName());
        project.setAudit(new ArrayList<>());

        boolean save = this.save(project);
        //创建支付信息
        if (save){
            projectService.createPay(project.getProjectNo());
        }
        return save;
    }

    @Override
    public Boolean updateInfo(ProjectPhase project) {
        ProjectPhase temp = this.getById(project.getId());//先查询得到历史信息
        String phaseId = temp.getPhaseId();
        String projectNo = temp.getProjectNo();
        List<Integer> audit = temp.getAudit();
        if (audit == null) {
            audit = new ArrayList<>();
        }
        project.setAudit(audit);
        project.setOperator(SecurityUtils.getLoginUser().getUser().getNickName());
        //更新审核人到audit  判断是否能够提交到下一个阶段
        PhaseDictionary config = dictionaryService.getById(phaseId);
        List<Integer> operatorId = config.getOperatorId();
        //指定了操作人的  添加操作人id到audit  指定了岗位操作人的 添加岗位id到audit
        Long userId = SecurityUtils.getLoginUser().getUserId();

        if (operatorId != null && operatorId.size() > 0) {
            audit.add(userId.intValue());
            project.setAudit(audit);
            //判断是否已经全部审核通过 是则设置该环节状态为已完成 2
            Integer needOperator = config.getNeedOperator();
            if (needOperator == 1) {//需要全部操作人同意才可设置状态status
                Set<Integer> auditSet = new HashSet<>(project.getAudit());
                // 判断 operatorId 中的所有元素是否都在 auditSet 中
                boolean result = auditSet.containsAll(operatorId);
                if (result) {//如果全部存在
                    project.setStatus("2");
                } else {
                    project.setStatus("1");
                }
            } else {//如果其中一个人同意就通过的情况
                boolean joinPersonChecks = operatorId.contains(userId.intValue());
                if (joinPersonChecks) {
                    project.setStatus("2");
                }
            }

        } else {
            //查询当前用户被指定为哪个岗位 获取岗位id
            LambdaQueryWrapper<ProjectParticipan> JoinPersonWrapper = new QueryWrapper<ProjectParticipan>().lambda()
                    .eq(ProjectParticipan::getProjectNo, projectNo);
            List<ProjectParticipan> joinPersonList = joinPersonService.list(JoinPersonWrapper);
            for (ProjectParticipan joinPerson : joinPersonList) {
                if (joinPerson.getParticipantId().equals(userId)) {
                    Long postId = joinPerson.getPostId();
                    audit.add(postId.intValue());//可能指定同一个人为项目经理 销售负责人 同一个人两个角色 不用二次审核
                }
            }
            //判断是否已经全部审核通过
            project.setAudit(audit);

            //判断needPersonId中的每一个值是否都存在于audit1
            List<Integer> audit1 = project.getAudit();
            List<Integer> needPostId = config.getPostId();
            //是否必须全部人同意才科流转到写一个环节 0否1是
            Integer allPerson = config.getAllPerson();
            if (allPerson == null || allPerson == 0) {
                //不需要全部操作人同意
                if (needPostId != null && needPostId.size() > 0) {
                    //有交集 说明存在
                    boolean exists = !Collections.disjoint(audit1, needPostId);
                    if (exists) {
                        project.setStatus("2");
                    }
                }
            }else {
                //都存在
                boolean allExist = audit1.containsAll(needPostId);
                // 初始化结果变量
                if (allExist) {
                    project.setStatus("2");
                }
            }
            //质保环节 如果是总经理
            if (userId.equals(100L) && "6".equals(phaseId)) {
                project.setStatus("2");
            }

        }

        //立项阶段 特殊处理 直接流转到下一步
        if (phaseId.equals("1")) {
            project.setStatus("2");//设置立项阶段 已完成
        }
        boolean update = this.updateById(project);
        //创建支付信息
        if (update){
            projectService.createPay(projectNo);
        }

        return update;
    }


    public void checkConfirm(String projectNo) {
        //可能提成发生变化 重新计算一下确认分配的绩效
        LambdaQueryWrapper<AllocationDetail> detailWrapper = new QueryWrapper<AllocationDetail>().lambda();
        detailWrapper.eq(AllocationDetail::getProjectNo, projectNo);
        List<AllocationDetail> detailList = detailService.list(detailWrapper);
        for (AllocationDetail detail : detailList) {
            BigDecimal already = detail.getAlready();
            if (already != null && already.compareTo(BigDecimal.ZERO)>0) {
//                detailService.allocationDetailConfirm(detail);
            }
        }
        //检测一下这个项目是不是已经全部确认分配完成了
        detailService.checkComplete(projectNo);

    }

    @Override
    public Boolean deleteInfo(String id) {
        return this.removeById(id);
    }

    @Override
    public ProjectPhase getInfoById(String id) {
        return this.getById(id);
    }

    @Override
    public List<ProjectPhase> getList(ProjectPhaseQuery query) {
        LambdaQueryWrapper<ProjectPhase> wrapper = new QueryWrapper<ProjectPhase>().lambda()
                .eq(query.getProjectNo() != null, ProjectPhase::getProjectNo, query.getProjectNo())
                .eq(query.getPhaseId() != null, ProjectPhase::getPhaseId, query.getPhaseId())
                .eq(query.getStatus() != null, ProjectPhase::getStatus, query.getStatus())
                .orderByAsc(ProjectPhase::getCreateTime);
//        dictTypeService.selectDictDataByType();
        return this.list(wrapper);
    }

    @Override
    public ProjectPhase getStatus(ProjectPhaseQuery query) {
        LambdaQueryWrapper<ProjectPhase> wrapper = new QueryWrapper<ProjectPhase>().lambda()
                .eq(query.getProjectNo() != null, ProjectPhase::getProjectNo, query.getProjectNo())
                .eq(query.getPhaseId() != null, ProjectPhase::getPhaseId, query.getPhaseId());
//                .eq(query.getStatus()!=null,ProjectPhase::getStatus,query.getStatus());
        return this.getOne(wrapper);
    }

    @Override
    public Map<String, Object> getStepList(ProjectPhaseQuery query) {
        LambdaQueryWrapper<ProjectPhase> wrapper = new QueryWrapper<ProjectPhase>().lambda()
                .eq(query.getProjectNo() != null, ProjectPhase::getProjectNo, query.getProjectNo())
                .eq(query.getPhaseId() != null, ProjectPhase::getPhaseId, query.getPhaseId())
                .eq(query.getStatus() != null, ProjectPhase::getStatus, query.getStatus())
                .orderByAsc(ProjectPhase::getCreateTime);
        // 获取 phaseList 和 phaseType 列表
        List<ProjectPhase> phaseList = this.list(wrapper);
        List<SysDictData> phaseType = dictTypeService.selectDictDataByType("phase_type");
// 创建一个新的列表，用于存储符合条件的对象
        List<SysDictData> resultPhaseList = new ArrayList<>();
        for (SysDictData dict : phaseType) {
            String dictValue = dict.getDictValue(); // 获取字典值
            boolean isMatched = false; // 标记是否找到匹配项

            // 遍历 phaseList 列表，查找匹配的 phaseId 并判断 status 是否为 2
            for (ProjectPhase phase : phaseList) {
                if (dictValue.equals(phase.getPhaseId())) {
                    if ("2".equals(phase.getStatus())) {
                        // 如果满足条件，设置 complete 和其他字段
                        dict.setComplete("2");
                        dict.setCompleteDate(phase.getUpdateTime());
                        dict.setCompletePerson(phase.getOperator());
                        dict.setOperator(dict.getDictLabel() + "-" + dict.getCompletePerson());
                        resultPhaseList.add(dict);
                        isMatched = true; // 标记已匹配
                        break; // 找到匹配后跳出内层循环
                    }
                }
            }

            // 如果没有找到匹配项，则设置为 complete="1"
            if (!isMatched) {
                dict.setComplete("1");
                dict.setCompleteDate(null);
                dict.setCompletePerson(null);
                dict.setOperator(dict.getDictLabel());
                resultPhaseList.add(dict);
            }
        }

        // 找出最大的 dictSort 且 complete 等于 2 的那个对象
        SysDictData maxDictSortItem = null;
        for (SysDictData dict : resultPhaseList) {
            if ("2".equals(dict.getComplete())) { // 只处理 complete 等于 2 的对象
                if (maxDictSortItem == null || dict.getDictSort() > maxDictSortItem.getDictSort()) {
                    maxDictSortItem = dict; // 更新最大值
                }
            }
        }

// 输出结果
        if (maxDictSortItem != null) {
//            System.out.println("最大 dictSort 且 complete 等于 2 的对象: " + maxDictSortItem);
        } else {
//            System.out.println("没有找到符合条件的对象");
        }

        // 构造返回的 Map
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("list", resultPhaseList); // 原来的返回值
        resultMap.put("completeObj", maxDictSortItem); // 最大 dictSort 且 complete 等于 2 的对象
        return resultMap;
    }

    @Override
    @Transactional
    public boolean rollBackPhase(ProjectPhase project) {
        try {
            //1.删除当前环节信息 先获取留言信息
            String remark = project.getRemark();
            String projectNo = project.getProjectNo();
            String phaseId = project.getBackId();//需要回退的环节id
            this.removeById(project.getId());

            //如果回退到核算环节 删除质保信息
            if ("5".equals(phaseId)) {
//                LambdaQueryWrapper<ProjectWarranty> warrantyWrapper = new QueryWrapper<ProjectWarranty>().lambda();
//                warrantyWrapper.eq(ProjectWarranty::getProjectNo, projectNo);
//                warrantyService.remove(warrantyWrapper);
            }


            //2.查询上一个环节信息 更新上一个环节为进行中 更新audit 不删除当前环节的已经生成的信息
            LambdaQueryWrapper<ProjectPhase> queryWrapper = new LambdaQueryWrapper<ProjectPhase>();
            queryWrapper.eq(ProjectPhase::getProjectNo, projectNo);
            queryWrapper.eq(ProjectPhase::getPhaseId, phaseId);
            queryWrapper.eq(ProjectPhase::getStatus, "2");//肯定是已完成的
            ProjectPhase one = this.getOne(queryWrapper);
            one.setRemark(remark);
            one.setAudit(new ArrayList<>());
            one.setStatus("1");//设置为进行中
            return this.updateById(one);
        } catch (Exception e) {
            throw new RuntimeException("回退环节出错,请联系管理员");
        }
    }

    @Override
    public boolean  projectCompelete(ProjectPhase projectPhase) {
        //1.查询结算金额
        Project projectInfo = projectService.getById(projectPhase.getProjectNo());
        //结算金额
        BigDecimal settlementAmount = projectInfo.getSettlementAmount();
        String projectNo = projectInfo.getProjectNo();
        String housekeeperProject = projectInfo.getHousekeeperProject();

        ProjectFeeQuery projectFeeQuery = new ProjectFeeQuery();
        projectFeeQuery.setHousekeeperProject(housekeeperProject);
        List<ProjectFee> feeList = feeService.getReceiveFee(projectFeeQuery);
        BigDecimal feeAmount = BigDecimal.ZERO;
        for (ProjectFee projectFee : feeList) {
            feeAmount = feeAmount.add(projectFee.getTotal());
        }

        //比较结算金额和总收款 相等则返回true
        // 比较收款金额是否大于等于结算金额
        if (feeAmount != null && settlementAmount != null) {
            if (feeAmount.compareTo(settlementAmount) >= 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<String> selectDistinctProjectNoByPhaseId(String phaseId) {
       return projectPhaseMapper.selectDistinctProjectNoByPhaseId(phaseId);
    }
}
